package com.neuedu.corejava.jdbc.dao.impl;

import java.lang.reflect.Parameter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.neuedu.corejava.jdbc.DBHelper;
import com.neuedu.corejava.jdbc.bean.Users;
import com.neuedu.corejava.jdbc.dao.IUsersDao;

public class UsersDaoImpl implements IUsersDao {

	@Override
	public boolean add(Users param) {
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;
		try {
			String sql = "insert into users(id,name,age,birthdate)values(SEQ_USERS.NEXTVAL,?,?,?)";
			stmt = conn.prepareStatement(sql);
			stmt.setString(1, param.getName());
			stmt.setInt(2, param.getAge());
			// 参数值是java.sql.Date,只能保存年月日；这里一般需要把util.Date转换为sql.Date
			// stmt.setDate(3,new java.sql.Date(param.getBirthDate().getTime()));
			// 参数值是java.sql.Time,只能保存时分秒；这里一般需要把util.Date转换为sql.Time
			// stmt.setTime(3,new java.sql.Time(param.getBirthDate().getTime()));

			// 参数值是java.sql.Timestamp,只能保存年月日时分秒；这里一般需要把util.Timestamp转换为sql.Date
			stmt.setTimestamp(3, new java.sql.Timestamp(param.getBirthDate().getTime()));
			int count = stmt.executeUpdate();// executeUpdate会返回sql更新数据时更新了多少行，更新行数
			if (count == 1) {
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBHelper.closeAll(null, stmt, conn);
		}

		return false;
	}

	@Override
	public boolean edit(Users param) {
		Users users = null;
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;

		try {
			String sql = "update  users set age=?,birthdate=? where id=?";
			stmt = conn.prepareStatement(sql);
			stmt.setInt(1, param.getId());
			stmt.setInt(2, param.getAge());
			stmt.setTimestamp(3, new java.sql.Timestamp(param.getBirthDate().getTime()));
			int count = stmt.executeUpdate();// executeUpdate会返回sql更新数据时更新了多少行，更新行数
			if (count == 1) {
				return true;
			}
		} catch (Exception e) {
			DBHelper.closeAll(null, stmt, conn);
		}
		return false;
	}

	@Override
	public boolean deleteById(int id) {
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;
		try {
			// 根据主键删除数据
			String sql = " delete from users where id=?";
			stmt = conn.prepareStatement(sql);
			stmt.setInt(1, id);
			int count = stmt.executeUpdate();
			if (count == 1) {
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBHelper.closeAll(null, stmt, conn);
		}
		return false;

	}

	@Override
	public Users findById(int id) {
		Users users = null;
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;
		ResultSet rs = null;

		try {
			String sql = "select id,name,age,birthdate from users where id=?";
			stmt.setInt(1, id);
			stmt = conn.prepareStatement(sql);
			rs = stmt.executeQuery();
			if (rs.next()) {// 根据主键或唯一键查询要么有一条数据，要么没有数据，可以用if进行判断
				int id1 = rs.getInt("id");
				String name = rs.getString("name");
				int age = rs.getInt("age");
				Date birthDate = rs.getDate("birthdate");
				users = new Users(id1, name, age, birthDate);

			}

		} catch (Exception e) {
			DBHelper.closeAll(rs, stmt, conn);
		}
		return users;
	}

	@Override
	public List<Users> findAll() {
		List<Users> list = new ArrayList<>();

		// 1.注册驱动 2.建立connection连接
		Connection conn = DBHelper.openConnection();
		// Statement statement;//可能造成sql注入攻击
		PreparedStatement stmt = null;// 可以防止sql注入攻击，在批量更新时有更好的性能
		ResultSet rs = null;

		try {
			// 3打开状态链接
			String sql = "select id,name name1,age,birthdate from users ";
			stmt = conn.prepareStatement(sql);
			// 4.执行sql
			rs = stmt.executeQuery();
			// 5.对sql执行结果进行处理
			while (rs.next()) {// next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id = rs.getInt(1);// 可以根据列的序号获取列的数据，列的序号从1开始，1表示第一列
				// String name =rs.getString("name");//可以根据列名或列的别名获取列的数据
				String name = rs.getString("name1");
				int age = rs.getInt("age");

				// getTimestamp,返回java.sql.Timestamp,sql.Timestamp是java.util.Date的子类，可以保存：年月日时分秒
				Date birthdate = rs.getTimestamp("birthdate");

				// getDate,返回java.sql.Date,sql.Date是java.util.Date的子类，可以保存：年月日
				// birthdate=rs.getDate("birthdate");//

				// getTime,返回java.sql.Time,sql.Time是java.util.Date的子类，可以保存：时分秒
				// birthdate =rs.getTime("birthdate");//班车发出时刻，飞机的飞行时刻表

				Users users = new Users(id, name, age, birthdate);
				list.add(users);

			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 6关闭连接
			DBHelper.closeAll(rs, stmt, conn);
		}

		return list;
	}

	@Override
	public List<Users> findByExample(Users param) {
		List<Users> list = new ArrayList<>();

		// 1.注册驱动 2.建立connection连接
		Connection conn = DBHelper.openConnection();
		// Statement statement;//可能造成sql注入攻击
		PreparedStatement stmt = null;// 可以防止sql注入攻击，在批量更新时有更好的性能
		ResultSet rs = null;

		try {
			// 3打开状态链接
			String sql = "select id,name name1,age,birthdate from users where name like ?";// 注意不要拼接sql
			stmt = conn.prepareStatement(sql);
			// 4.执行sql
			// 如果sql有参数，即有？号，需要进行参数填充
			stmt.setString(1, "%" + param.getName() + "%");// 参数的序号是从1开始的，1表示第一个参数
			rs = stmt.executeQuery();
			// 5.对sql执行结果进行处理
			while (rs.next()) {// next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id = rs.getInt(1);// 可以根据列的序号获取列的数据，列的序号从1开始，1表示第一列
				// String name =rs.getString("name");//可以根据列名或列的别名获取列的数据
				String name = rs.getString("name1");
				int age = rs.getInt("age");

				// getTimestamp,返回java.sql.Timestamp,sql.Timestamp是java.util.Date的子类，可以保存：年月日时分秒
				Date birthdate = rs.getTimestamp("birthdate");

				// getDate,返回java.sql.Date,sql.Date是java.util.Date的子类，可以保存：年月日
				// birthdate=rs.getDate("birthdate");//

				// getTime,返回java.sql.Time,sql.Time是java.util.Date的子类，可以保存：时分秒
				// birthdate =rs.getTime("birthdate");//班车发出时刻，飞机的飞行时刻表

				Users users = new Users(id, name, age, birthdate);
				list.add(users);

			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 6关闭连接
			DBHelper.closeAll(rs, stmt, conn);
		}

		return list;
	}

	@Override
	public List<Users> findByPage(Integer page, int size) {
		List<Users> list = new ArrayList<>();

		// 1.注册驱动 2.建立connection连接
		Connection conn = DBHelper.openConnection();
		// Statement statement;//可能造成sql注入攻击
		PreparedStatement stmt = null;// 可以防止sql注入攻击，在批量更新时有更好的性能
		ResultSet rs = null;

		try {
			// 3打开状态链接
			String sql = "select * from(select rownum rn, id,name name1,age,birthdate from users where rownum<=?)where rn>?";// 注意不要拼接sql
			stmt = conn.prepareStatement(sql);
			// 4.执行sql
			// 如果sql有参数，即有？号，需要进行参数填充
			stmt.setInt(1, page * size);// 参数的序号是从1开始的，1表示第一个参数
			stmt.setInt(2, (page - 1) * size);

			rs = stmt.executeQuery();
			// 5.对sql执行结果进行处理
			while (rs.next()) {// next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id = rs.getInt(1);// 可以根据列的序号获取列的数据，列的序号从1开始，1表示第一列
				// String name =rs.getString("name");//可以根据列名或列的别名获取列的数据
				String name = rs.getString("name1");
				int age = rs.getInt("age");

				// getTimestamp,返回java.sql.Timestamp,sql.Timestamp是java.util.Date的子类，可以保存：年月日时分秒
				Date birthdate = rs.getTimestamp("birthdate");

				// getDate,返回java.sql.Date,sql.Date是java.util.Date的子类，可以保存：年月日
				// birthdate=rs.getDate("birthdate");//

				// getTime,返回java.sql.Time,sql.Time是java.util.Date的子类，可以保存：时分秒
				// birthdate =rs.getTime("birthdate");//班车发出时刻，飞机的飞行时刻表

				Users users = new Users(id, name, age, birthdate);
				list.add(users);

			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 6关闭连接
			DBHelper.closeAll(rs, stmt, conn);
		}

		return list;
	}

	@Override
	public int deleteByids(int[] ids) {
		int result = 0;
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;

		// 业务说明：批量删除，只要有一条删除失败，则所有的都不删除

		try {
			conn.setAutoCommit(false);
			String sql = "delede from users where id=?";
			stmt = conn.prepareStatement(sql);
			for (int id : ids) {
				stmt.setInt(1, id);
				stmt.addBatch();// 批量发送,每循环异常就是一批数量
			}
			int[] counts = stmt.executeBatch();// 返回一个数组，保存了每批数据更新的情况，每批数据更新的数量
			for (int i : counts) {// 统计有多少批数据删除成功
				if (i == 1) {
					result++;
				}
			}
			if (result == ids.length) {
				conn.commit();// 提交事务
				conn.setAutoCommit(true);// 开启（还原）数据库事务
			} else {
				conn.rollback();// 回滚事务
			}
		} catch (SQLException e) {
			e.printStackTrace();
			if (conn != null) {//删除数据，如有部分删除异常，则需要全部回滚
				try {
					conn.rollback();
					conn.setAutoCommit(true);
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}

		} finally {
			DBHelper.closeAll(null, stmt, conn);
		}

		return result;
	}

	@Override
	public int addAll(List<Users> users) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int editAll(List<Users> users) {
		// TODO Auto-generated method stub
		return 0;
	}

}
